﻿using System.Collections.Generic;
using Engine;
using Game;
using Mekiasm.Ore;

namespace Mekiasm
{
    public class LightPoint
    {
        public int oldValue;
        public int Light;
        public double endTime;
    }
    public class LightSystem
    {
        public static Dictionary<Point3, LightPoint> valuePairs = new Dictionary<Point3, LightPoint>();
        public static double LastMakeStoneTime = 0;
        public static Vector3 MakePosition = Vector3.Zero;
        public static int MakeCount = 0;
        public static List<Point3> MakePoints = new List<Point3>();
        public static void AddLightPoint(Point3 point3, LightPoint lightPoint)
        {
            if (!valuePairs.TryGetValue(point3, out LightPoint point))
            {
                valuePairs.Add(point3, lightPoint);
                ILibrary.SubsystemTerrain.ChangeCell(point3.X, point3.Y, point3.Z, ILibrary.setExtraData(EmittedLight.Index, lightPoint.Light));
            }
            else
            {
                point.endTime = lightPoint.endTime;
            }
        }
        public static void RemoveLightPoint(Point3 point3)
        {
            if (LightSystem.valuePairs.TryGetValue(point3, out LightPoint light))
            {
                int va = ILibrary.SubsystemTerrain.Terrain.GetCellValueFast(point3.X, point3.Y, point3.Z);
                if (ILibrary.GetBasicValue(va) == EmittedLight.Index)
                    ILibrary.SubsystemTerrain.ChangeCell(point3.X, point3.Y, point3.Z, light.oldValue);
                valuePairs.Remove(point3);
            }
        }
        private static Color[] Maps = new Color[] { Color.Red, Color.Yellow, Color.Green, Color.Blue, Color.White };
        public static void MakeMeteStone()
        {
            if (MakeCount <= 0 && ILibrary.SubsystemSky.MoonPhase == 0 && MakePoints.Count > 0 && ILibrary.SubsystemSky.SkyLightIntensity < 0.1f)
            {
                Point3 point = MakePoints[0];
                MakePoints.RemoveAt(0);
                LastMakeStoneTime = ILibrary.SubsystemGameInfo.TotalElapsedGameTime;
                MakeCount = (new Game.Random()).Int(20, 100);
                ILibrary.SubsystemTerrain.ChangeCell(point.X, point.Y, point.Z, 0);
                MakePosition = new Vector3(point.X + ILibrary.random.Int(-10, 10), 200, point.Z + ILibrary.random.Int(-10, 10));
                foreach (var player in ILibrary.Players.ComponentPlayers)
                {
                    player.ComponentGui.DisplaySmallMessage("陨石来袭", Color.Red, false, true);
                }
            }
            else
            {
                if (MakeCount > 0 && Time.PeriodicEvent(0.1, 0.05))
                {
                    var p = Terrain.ToCell(MakePosition);
                    SubsystemProjectiles subsystemProjectiles = ILibrary.Project.FindSubsystem<SubsystemProjectiles>();
                    Projectile projectile = subsystemProjectiles.AddProjectile(
                        OreSkyStone.Index, MakePosition + new Vector3(ILibrary.random.Float(-5f, 5f), 0, ILibrary.random.Float(-5f, 5f)),
                        -3 * Vector3.UnitY, Vector3.Zero, null);
                    projectile.ProjectileStoppedAction = ProjectileStoppedAction.Disappear;
                    projectile.OnRemove = delegate {
                        var pp = Terrain.ToCell(projectile.Position);
                        ILibrary.subsystemExplosions.AddExplosion(pp.X, pp.Y, pp.Z, 1f, false, false);
                        ILibrary.subsystemExplosions.m_explosionParticleSystem.SetExplosionCell(pp, 1f);
                    };
                    subsystemProjectiles.AddTrail(projectile, Vector3.Zero, new SmokeTrailParticleSystem(20, 0.5f, float.MaxValue, Maps[ILibrary.random.Int(0, Maps.Length - 1)]));
                    int x = ILibrary.random.Int(p.X - 16, p.X + 16);
                    int y = ILibrary.random.Int(20, 64);
                    int z = ILibrary.random.Int(p.Z - 16, p.Z + 16);
                    //生成陨石
                    var v = ILibrary.SubsystemTerrain.Terrain.GetCellContents(x, y, z);
                    if (ILibrary.random.Bool(0.6f) && (v == GraniteBlock.Index || v == DirtBlock.Index))
                    {
                        ILibrary.SubsystemTerrain.ChangeCell(x, y, z, OreSkyStone.Index);
                        MakeCount--;
                    }
                }
            }

        }

        public static void Update()
        {
            MakeMeteStone();
            List<Point3> points = new List<Point3>();
            foreach (var item in valuePairs)
            {
                if (ILibrary.SubsystemGameInfo.TotalElapsedGameTime > item.Value.endTime)
                {
                    points.Add(item.Key);
                }
            }
            for (int i = 0; i < points.Count; i++)
            {
                RemoveLightPoint(points[i]);
            }
        }
    }
}
